#include<iostream>
#include<vector>
#include<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

/*
 * 卷积使用掩膜来计算，需要注意两个关键核心：注意边缘的处理，注意图像的遍历的开始
 * 
 * 
*/

void convolution_3x3(uint8_t * input, uint8_t * output, int width, int height) {
    // 定义一个3x3的卷积核
    int kernel[3][3] = {
        {-1, -1, -1},
        {-1, 8, -1},
        {-1, -1, -1}
    };

    // int kernel[3][3] = {
    //     {1, 1, 1},
    //     {1, 1, 1},
    //     {1, 1, 1}
    // };

    for (int i = 1;i < height -1;i++)
    {
        for (int j = 1;j < width -1;j++)
        {
            int sum = 0;

            for (int k = -1;k < 2;k++)
            {
                for (int p = -1;p < 2;p++)
                {
                    sum += input[(i+k)*width+j+p] * kernel[k+1][p+1];
                }
            }

            if (sum < 0)
            {
                sum = 0;
            }
            else if (sum > 255)
            {
                sum = 255;
            }
            output[i*width+j] = uint8_t(sum);

        }
    }
    
}


void save_data_toFile(const char * path,uint8_t * mem,uint32_t bytes)
{
    FILE * fp = fopen(path,"wb");
    fwrite(mem,sizeof(uint8_t),bytes,fp);
    fclose(fp);
}

void open_data_toMem(const char * path,uint8_t * mem,uint32_t bytes)
{
    FILE * fp = fopen(path,"rb");
    fread(mem,sizeof(uint8_t),bytes,fp);
    fclose(fp);
}

int main(){

    

	uint8_t * data_ptr = (uint8_t *)malloc(640*800);
    uint8_t * out_ptr = (uint8_t *)malloc(640*800);

	open_data_toMem("./data/640*800.raw",data_ptr,640*800);

    convolution_3x3(data_ptr, out_ptr, 640, 800);

	// // Mat type, Size(width,height) ---> (cols,rows)
	Mat image1 = cv::Mat(cv::Size(640,800),CV_8UC1,data_ptr);
    Mat image2 = cv::Mat(cv::Size(640,800),CV_8UC1,out_ptr);

	imshow("Image1", image1);
    imshow("Image2", image2);
	waitKey(0);
	free(data_ptr);
    free(out_ptr);
	return 0;
}




